<template>
  <t-dialog
    :header="title"
    :visible="open"
    width="680px"
    placement="center"
    :footer="false"
    destroy-on-close
    @close="cancel"
  >
    <t-form ref="FormRef" :data="form" :rules="rules" label-width="100px" @submit="onSubmit">
      <t-form-item label="上级菜单" name="parentId">
        <t-tree-select
          v-model="form.parentId"
          :data="data"
          placeholder="请选择上级菜单"
          :keys="{ value: 'menuId', label: 'menuName' }"
        />
      </t-form-item>
      <t-form-item label="菜单类型" name="menuType">
        <t-radio-group v-model="form.menuType">
          <t-radio value="M">目录</t-radio>
          <t-radio value="C">菜单</t-radio>
          <t-radio value="F">按钮</t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item v-if="form.menuType != 'F'" label="菜单图标" name="icon">
        <icon-picker v-model:icon="form.icon" clearable />
      </t-form-item>
      <t-form-item label="菜单名称" name="menuName">
        <t-input v-model="form.menuName" placeholder="请输入菜单名称" />
      </t-form-item>
      <t-form-item label="显示排序" name="orderNum">
        <t-input-number v-model="form.orderNum" :min="0" />
      </t-form-item>
      <t-form-item v-if="form.menuType != 'F'" name="isFrame">
        <template #label>
          <t-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          是否外链
        </template>
        <t-radio-group v-model="form.isFrame">
          <t-radio value="0">是</t-radio>
          <t-radio value="1">否</t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item v-if="form.menuType != 'F'" name="path">
        <template #label>
          <t-tooltip content="访问的路由地址，如：`user`，如外网地址需内链访问则以`http(s)://`开头" placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          路由地址
        </template>
        <t-input v-model="form.path" placeholder="请输入路由地址" />
      </t-form-item>
      <t-form-item v-if="form.menuType == 'C'" name="component">
        <template #label>
          <t-tooltip content="访问的组件路径，如：`system/user/index`，默认在`views`目录下" placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          组件路径
        </template>
        <t-input v-model="form.component" placeholder="请输入组件路径" />
      </t-form-item>
      <t-form-item v-if="form.menuType != 'M'" name="perms">
        <template #label>
          <t-tooltip
            content="控制器中定义的权限字符，如：@PreAuthorize(`@ss.hasPermi('system:user:list')`)"
            placement="top"
          >
            <help-circle-filled-icon />
          </t-tooltip>
          权限字符
        </template>
        <t-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
      </t-form-item>
      <t-form-item v-if="form.menuType == 'C'" name="query">
        <template #label>
          <t-tooltip content='访问路由的默认传递参数，如：`{"id": 1, "name": "ry"}`' placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          路由参数
        </template>
        <t-input v-model="form.query" placeholder="请输入路由参数" maxlength="255" />
      </t-form-item>
      <t-form-item v-if="form.menuType == 'C'" name="isCache">
        <template #label>
          <t-tooltip content="选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致" placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          是否缓存
        </template>
        <t-radio-group v-model="form.isCache">
          <t-radio value="0">缓存</t-radio>
          <t-radio value="1">不缓存</t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item v-if="form.menuType != 'F'" name="visible">
        <template #label>
          <t-tooltip content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问" placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          显示状态
        </template>
        <t-radio-group v-model="form.visible">
          <t-radio value="0">显示</t-radio>
          <t-radio value="1">隐藏</t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item name="status">
        <template #label>
          <t-tooltip content="选择停用则路由将不会出现在侧边栏，也不能被访问" placement="top">
            <help-circle-filled-icon />
          </t-tooltip>
          菜单状态
        </template>
        <t-radio-group v-model="form.status">
          <t-radio value="0">正常</t-radio>
          <t-radio value="1">停用</t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item style="float: right">
        <t-button variant="outline" @click="cancel">取消</t-button>
        <t-button style="margin-left: 10px" theme="primary" type="submit" :loading="loading">确定</t-button>
      </t-form-item>
    </t-form>
  </t-dialog>
</template>

<script setup lang="ts">
import { HelpCircleFilledIcon } from 'tdesign-icons-vue-next';
import type { Data, SubmitContext, ValidateTriggerType } from 'tdesign-vue-next';
import { MessagePlugin } from 'tdesign-vue-next';
import { ref, watch } from 'vue';

import { add, edit, getInfo } from '@/api/system/permission';
import { getPermissionStore } from '@/store/modules/permission';

import IconPicker from './iconPicker.vue';

const permissionStore = getPermissionStore();
// 声明 props
const props = defineProps({
  title: {
    type: String,
    default: '',
  },
  menuOptions: {
    type: Array<any>,
    default: () => [],
  },
  dict: {
    type: Object,
    default: () => ({}),
  },
});

const INITIAL_DATA = {
  id: null, // 菜单ID
  parentId: null, // 上级菜单
  menuType: 'M', // 菜单类型，默认为目录
  icon: '', // 菜单图标
  menuName: '', // 菜单名称
  orderNum: 0, // 显示排序
  isFrame: '1', // 是否外链，默认否
  path: '', // 路由地址
  component: '', // 组件路径
  perms: '', // 权限字符
  query: '', // 路由参数
  isCache: '0', // 是否缓存，默认缓存
  visible: '0', // 显示状态，默认显示
  status: '0', // 菜单状态，默认正常
};

const form = ref({ ...INITIAL_DATA });

const data = ref([{ menuId: 0, menuName: '主类目', children: [] }]);
watch(
  () => props.menuOptions,
  (newVal) => {
    data.value[0].children = newVal;
  },
  { immediate: true },
);

const rules = {
  menuName: [
    {
      required: true,
      message: '请输入菜单名称',
      trigger: 'blur' as ValidateTriggerType, // 显式转换为合法枚举类型
    },
  ],
};

// 声明 emits
const emit = defineEmits(['submit']);

// 组件内逻辑
const open = ref(false);
const changeOpen = (bol: boolean, menuId: any, title: string) => {
  open.value = bol;
  form.value.parentId = menuId || 0;
  if (bol && title === '修改菜单') {
    getInfo(menuId).then((res: any) => {
      form.value = res.data;
    });
  }
};

const loading = ref(false);

const submitData = (method: Promise<any>) => {
  method.then((_res) => {
    emit('submit');
    MessagePlugin.success('提交成功');
    cancel();
    permissionStore.buildAsyncRoutes();
  });
};
const onSubmit = async ({ validateResult: _validateResult, firstError }: SubmitContext<Data>) => {
  loading.value = true;
  if (!firstError) {
    try {
      if (props.title === '修改菜单') {
        submitData(edit(form.value));
      } else {
        submitData(add(form.value));
      }
    } catch (e: any) {
      // MessagePlugin.error(e.message);
    }
  } else {
    MessagePlugin.warning(firstError);
  }
  loading.value = false;
};

const cancel = () => {
  changeOpen(false, null, '');
  form.value = { ...INITIAL_DATA };
};

defineExpose({
  changeOpen,
});
</script>
